/*
 * ProbabilityCombinationVectorsHistoryComponent.java
 *
 * Created on 11 de Julho de 2011, 10:58
 */

package intopo.demonstrator.partnerclassification.gui;

import intopo.demonstrator.partnerclassification.State;
import intopo.demonstrator.partnerclassification.Parameters;

import util.math.Rational;

import java.awt.Graphics;
import java.awt.Color;
import java.beans.*;
import java.io.Serializable;

/**
 * A component that displays the history of the probability and combination vectors.
 *
 * @author pedro
 */
public class ProbabilityCombinationVectorsHistoryComponent
	extends AbstractStateHistoryComponent
	implements Serializable
{
	public ProbabilityCombinationVectorsHistoryComponent ()
	{
		Listener l = new Listener ();
		this.addMouseListener (l);
		this.addMouseMotionListener (l);
		setYLabel ("probability");
		setYRange (0, 1);
		setYTics (0, Math.pow (2, -Model.parameters.getNumberBitsProbability ()), 1);
		this.setTitle ("Probability and Combination Vectors");
	}
	public void parametersChanged ()
	{
		// figure a reasonable step
		int exp = -Model.parameters.getNumberBitsProbability ();
		double step;
		do {
			step = Math.pow (2, exp);
//			System.out.println ("2^" + exp);
			exp++;
		} while (1 / step > plotArea.height / 10 && step < 1);
		setYTics (0, step, 1);
//		System.out.println ("Step: " + step);
		super.parametersChanged ();
	}
	public void paintHistory (Graphics g)
	{
		int x, yPrevious;
//		paintAxis (g, "time");
		for (int i = Model.parameters.getPoolSize () - 1; i >= 0; i--) {
			yPrevious = -1;
			for (x = Model.history.size () - 1; x >= 0; x--) {
				if (!this.isVisible (x, 0)) {
					x = -1;
				}
				else {
					State s = Model.history.get (x);
					Rational y = s.getProbabilityAsRational (i);
					this.toComponentCoordinateSystem (x, y.toBigDecimal ().doubleValue ());
					Rational green = s.getCombination (i).probabilityBehaveAcceptably ();
					g.setColor (new Color (0, green.toBigDecimal ().floatValue (), 0));
					if (yPrevious != -1) {
						g.drawLine ((int) xc + 2, yPrevious, (int) xc, (int) yc);
					}
					else {
						g.fillRect ((int) xc, (int) yc, 1, 1);
					}
					yPrevious = (int) yc;
				}
			}
		}
	}
	/**
	 * Listener responsible for updating the tool tip text when the mouse moves.
	 */
	private class Listener
		extends java.awt.event.MouseAdapter
	{
		public void mouseMoved (java.awt.event.MouseEvent mouseEvent)
		{
			int x = mouseEvent.getX ();
			x /= 2;
			if (x >= Model.history.size ()) {
				return ;
			}
			int height = getHeight ();
			int distance = Integer.MAX_VALUE;
			int mouse = mouseEvent.getY ();
			String toolTip = null;
			State state = Model.getHistory (x);
			for (int i = Model.parameters.getPoolSize () - 1; i >= 0; i--) {
				x = 0;
				Rational ry = state.getProbabilityAsRational (i).multiply (new Rational (plotArea.height));
				int y1 = margin.top
					+ plotArea.height
					- (int) (ry.numerator ().longValue () / ry.denominator ().longValue ());
//				int y1 = canvasAnchor.y
//					+ canvas.height
//					- (int) (ry.numerator ().longValue () / ry.denominator ().longValue ());
				int d = Math.abs (y1 - mouse);
				if (d < distance) {
					toolTip = state.getCombination (i).toString ();
					distance = d;
				}
				else if (d == distance) {
					toolTip += "  " + state.getCombination (i).toString ();
				}
			}
			if (distance <= MIN_DISTANCE_I) {
				setToolTipText (toolTip);
			}
			else {
				setToolTipText (null);
			}
		}
	}
}
